package com.enki.cigarettes.controller;

import com.enki.cigarettes.controller.vo.request.BindPhoneRequestVo;
import com.enki.cigarettes.controller.vo.request.UserRequestVo;
import com.enki.cigarettes.controller.vo.response.UserResponseVo;
import com.enki.cigarettes.entity.CouponT;
import com.enki.cigarettes.entity.UserCouponT;
import com.enki.cigarettes.entity.UserT;
import com.enki.cigarettes.enums.UserEnums;
import com.enki.cigarettes.handler.Response;
import com.enki.cigarettes.redis.RedisBaseOperation;
import com.enki.cigarettes.repository.ProductFollowTRepository;
import com.enki.cigarettes.repository.UserCouponTRepository;
import com.enki.cigarettes.repository.UserTRepository;
import com.enki.cigarettes.statics.StaticKeys;
import com.enki.cigarettes.utils.ali.SmsSendUtil;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.*;


/**
 * @author WCS.Wang
 * @version V1.0
 * @Package com.enki.cigarettes.controller
 * @Name e-cigarettes-shop-api-module
 * @Description: TODO 用户数据层
 * @date 2019-07-23
 */
@RestController
@RequestMapping("/api/users")
@Slf4j
public class UserController {

    @Autowired
    ProductFollowTRepository productFollowTRepository;
    @Autowired
    UserCouponTRepository userCouponTRepository;
    @Autowired
    UserTRepository userTRepository;
    @Resource
    RedisBaseOperation<String> stringRedisBaseOperation;

    @PostMapping
    public Object login(HttpSession session) {
        try {
            session.setAttribute(StaticKeys.USER_ID, "5c09d7019932e5f2430d2030");
            return Response.success();
        } catch (Exception e) {
            log.error("登录失败：" + e.getMessage());
            e.printStackTrace();
            return Response.serverError_500("登录失败");
        }
    }

    @ApiOperation(value = "获取验证码")
    @GetMapping(value = "/code/{phone}/{language}")
    public Object validateCode(@PathVariable String phone, @PathVariable int language) {
        try {
            if (StringUtils.isBlank(phone)) {
                return Response.badRequest_400("请输入手机号");
            }
            // 联系人手机号码验证
            String phoneRegex = "^(13[0-9]|14[579]|15[0-3,5-9]|16[6]|17[0135678]|18[0-9]|19[89])\\d{8}$";
            if (!phone.matches(phoneRegex)) {
                return Response.badRequest_400("手机号码格式不正确");
            }
            UserT userPhone = userTRepository.findFirstByPhoneAndUserSource(phone, language);
            if (userPhone != null) {
                return Response.badRequest_400("当前手机号已存在");
            }
            String validateCode = SmsSendUtil.getPhoneValidate(6);
            SmsSendUtil.sendValidate(phone, validateCode);
            stringRedisBaseOperation.saveOrUpdate(phone, validateCode);
//            return Response.success(validateCode, StaticKeys.SUCCESS);
            return Response.success();
        } catch (Exception e) {
            log.error("获取验证码失败：" + e.getMessage());
            e.printStackTrace();
            return Response.serverError_500("获取验证码失败");
        }
    }

    @ApiOperation(value = "更新手机号")
    @PostMapping("/bind")
    public Object bindPhone(@RequestBody BindPhoneRequestVo item, HttpSession session) {
        try {
            Object sessionId = session.getAttribute(StaticKeys.USER_ID);
            if (sessionId == null) {
                return Response.unauthorized_401("身份过期，请重新登录");
            }
            if (StringUtils.isBlank(item.getPhone())) {
                return Response.badRequest_400("请输入手机号");
            }
            // 联系人手机号码验证
            String phoneRegex = "^(13[0-9]|14[579]|15[0-3,5-9]|16[6]|17[0135678]|18[0-9]|19[89])\\d{8}$";
            if (!item.getPhone().matches(phoneRegex)) {
                return Response.badRequest_400("手机号码格式不正确");
            }
            if (StringUtils.isBlank(item.getValidate())) {
                return Response.badRequest_400("请输入验证码");
            }
            Object rediscode = stringRedisBaseOperation.get(item.getPhone());
            if (rediscode == null) {
                return Response.badRequest_400("验证码失效");
            }
            //对比验证码
            if (!StringUtils.equals(item.getValidate(), rediscode.toString().trim())) {
                return Response.badRequest_400("验证码错误");
            }
            UserT userPhone = userTRepository.findFirstByPhoneAndUserSource(item.getPhone(), item.getLanguage());
            if (userPhone != null) {
                return Response.badRequest_400("当前手机号已存在");
            }
            UserT bean = userTRepository.findOneById(sessionId.toString());
            if (bean != null) {
                bean.setPhone(item.getPhone());
                userTRepository.save(bean);
                return Response.success();
            } else {
                return Response.badRequest_400("不存在的用户信息");
            }
        } catch (Exception e) {
            log.error("更新手机号失败：" + e.getMessage());
            e.printStackTrace();
            return Response.serverError_500("更新手机号失败");
        }
    }

    @ApiOperation(value = "获取用户信息")
    @GetMapping
    public Object findUserById(HttpSession session) {
        try {
            Object sessionId = session.getAttribute(StaticKeys.USER_ID);
            if (sessionId == null) {
                return Response.unauthorized_401("身份过期，请重新登录");
            }
            UserT bean = userTRepository.findOneById(sessionId.toString());
            if (bean != null) {
                UserResponseVo userVo = new UserResponseVo();
                BeanUtils.copyProperties(bean, userVo);
                userVo.setGenderName(UserEnums.Gender.getName(bean.getGender()));
                return Response.success(userVo, StaticKeys.SUCCESS);
            } else {
                return Response.badRequest_400("不存在的用户信息");
            }
        } catch (Exception e) {
            log.error("获取用户信息失败：" + e.getMessage());
            e.printStackTrace();
            return Response.serverError_500("获取用户信息失败");
        }
    }

    @ApiOperation(value = "更新用户信息")
    @PutMapping
    public Object update(@RequestBody UserRequestVo item, HttpSession session) {
        try {
            Object sessionId = session.getAttribute(StaticKeys.USER_ID);
            if (sessionId == null) {
                return Response.unauthorized_401("身份过期，请重新登录");
            }
            if (StringUtils.isBlank(item.getNickname())) {
                return Response.badRequest_400("请输入昵称");
            }
            if (StringUtils.isBlank(item.getRealname())) {
                return Response.badRequest_400("请输入姓名");
            }
            if (StringUtils.isBlank(item.getPhone())) {
                return Response.badRequest_400("请输入手机号");
            }
            // 联系人手机号码验证
            String phoneRegex = "^(13[0-9]|14[579]|15[0-3,5-9]|16[6]|17[0135678]|18[0-9]|19[89])\\d{8}$";
            if (!item.getPhone().matches(phoneRegex)) {
                return Response.badRequest_400("手机号码格式不正确");
            }
            if (StringUtils.isBlank(item.getBirthday())) {
                return Response.badRequest_400("请输入生日");
            }
            if (StringUtils.isBlank(item.getCity())) {
                return Response.badRequest_400("请输入地区");
            }
            UserT bean = userTRepository.findOneById(sessionId.toString());
            if (bean != null) {
                bean.setNickname(item.getNickname());
                bean.setRealname(item.getRealname());
                bean.setGender(item.getGender());
                bean.setBirthday(item.getBirthday());
                bean.setPhone(item.getPhone());
                bean.setCity(item.getCity());
                userTRepository.save(bean);
                return Response.success();
            } else {
                return Response.badRequest_400("不存在的用户信息");
            }
        } catch (Exception e) {
            log.error("更新用户信息失败：" + e.getMessage());
            e.printStackTrace();
            return Response.serverError_500("更新用户信息失败");
        }
    }

    @ApiOperation(value = "获会员首页信息")
    @GetMapping(value = "/data")
    public Object findMemberData(HttpSession session) {
        try {
            Object sessionId = session.getAttribute(StaticKeys.USER_ID);
            if (sessionId == null) {
                return Response.unauthorized_401("登录身份失效，请重新登录");
            }
            UserT userBean = userTRepository.findOneById(sessionId.toString());
            if (userBean == null) {
                return Response.badRequest_400("登录身份失效，请重新登录");
            }
            Map<String, Object> responseData = new HashMap<>();
            // 商品收藏数量
            long followAmount = productFollowTRepository.countByUserTId(sessionId.toString());
            // 优惠券数量
            Specification<UserCouponT> specification = new Specification<UserCouponT>() {
                @Override
                public Predicate toPredicate(Root<UserCouponT> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
                    List<Predicate> predicateList = new ArrayList<>();
                    Root<CouponT> couponTRoot = query.from(CouponT.class);
                    predicateList.add(criteriaBuilder.equal(root.get("userId"), sessionId.toString()));
                    predicateList.add(criteriaBuilder.equal(root.get("status"), false));
                    predicateList.add(criteriaBuilder.equal(couponTRoot.get("id"), root.get("couponTId")));
                    predicateList.add(criteriaBuilder.equal(couponTRoot.get("status"), true));
                    predicateList.add(criteriaBuilder.greaterThan(couponTRoot.get("effectiveEndTime"), new Date()));
                    predicateList.add(criteriaBuilder.equal(couponTRoot.get("source"), userBean.getUserSource()));
                    Predicate[] predicates = new Predicate[predicateList.size()];
                    query.where(predicateList.toArray(predicates));
                    return query.getRestriction();
                }
            };
            long couponAmount = userCouponTRepository.count(specification);
            // 余额
            UserT user = userTRepository.findOneById(sessionId.toString());
            responseData.put("followAmount", followAmount);
            responseData.put("couponAmount", couponAmount);
            responseData.put("curBalance", user.getCurBalance());
            responseData.put("userBean", user);
            return Response.success(responseData, StaticKeys.SUCCESS);
        } catch (Exception e) {
            log.error("获取首页信息失败：" + e.getMessage());
            e.printStackTrace();
            return Response.serverError_500("获取首页信息失败");
        }
    }

}
